import * as React from 'react';
import './EditorInputStep.scss';
import classNames from 'classnames';
import { Vector2 } from 'three';
import { EChangeType, IMousePoints } from '@/interface/common';

export enum EInputStepType {
  Int,
  Float,
}
export interface IInputStepProps {
  /** 唯一标识 */
  id?: any;
  /** 初始数值 */
  num: number;
  /** 步伐 */
  step?: number;
  /** 类型 */
  type?: EInputStepType;
  /** 拖动的比例 */
  dragRatio?: number;
  /** 改变数值 */
  onChange?: (num: number, id: any) => void;
  /** 是否可以点击复制 */
  isCopy?: boolean;
  /** 是否可以编辑 */
  disabled?: boolean;
}

export default function InputStep(props: IInputStepProps) {
  let {
    num,
    step = 0.01,
    type = EInputStepType.Int,
    dragRatio = 1,
    disabled = false,
    onChange = () => {},
  } = props;
  if (num.toString().split('.')[1]?.length > 5) {
    num = Number(Number(num).toFixed(5));
  }
  /** 是否显示蒙层 */
  let [isMaskShow, setIsMaskShow] = React.useState(false);
  let [mousePoint, setMousePoint] = React.useState<IMousePoints>({
    mouseStart: new Vector2(),
    mouseEnd: new Vector2(),
  });
  // 是否可以拖拽
  let [canDrag, setCanDrag] = React.useState(false);
  let inputRef = React.useRef<HTMLInputElement>(null);

  const onMouseEnterInput = () => {
    if (disabled) return;
    setIsMaskShow(true);
  };

  const onMouseLeaveInput = () => {
    setIsMaskShow(false);
  };

  const inputBlur = () => {
    if (!(num ?? 0)) {
      onChange(0, props.id);
    } else {
      onChange(Number(num), props.id);
    }
  };

  const sliderDown = (e: React.MouseEvent<HTMLDivElement>) => {
    setCanDrag(true);
    setMousePoint({
      ...mousePoint,
      mouseStart: new Vector2(e.clientX, e.clientY),
    });
  };
  const sliderMove = (e: React.MouseEvent<HTMLDivElement>) => {
    if (!canDrag) return;
    let { mouseStart } = mousePoint;
    onChange(num + ((e.clientX - mouseStart.x) * step) / dragRatio, props.id);
    setMousePoint({
      ...mousePoint,
      mouseStart: new Vector2(e.clientX, e.clientY),
    });
  };
  const sliderUp = () => {
    setCanDrag(false);
  };
  const sliderLeave = (e: React.MouseEvent<HTMLDivElement>) => {
    const mousemoveHandle = (e: any) => {
      sliderMove(e);
    };
    const mouseupHandle = () => {
      sliderUp();
      document.removeEventListener('mousemove', mousemoveHandle);
      document.removeEventListener('mouseup', mouseupHandle);
    };
    document.addEventListener('mousemove', mousemoveHandle);
    document.addEventListener('mouseup', mouseupHandle);
  };

  const changeNum = (type: EChangeType, e?: React.ChangeEvent<HTMLInputElement>) => {
    if (disabled) return;
    if (type === EChangeType.Increase) {
      onChange(+num + step, props.id);
    } else if (type === EChangeType.Decrease) {
      onChange(+num - step, props.id);
    } else if (type === EChangeType.Update && e) {
      let value = e.target.value;
      if (!isNaN(Number(value))) {
        onChange(value as any, props.id);
      }
    }
  };
  const foceInput = () => {
    inputRef.current?.focus();
  };
  React.useEffect(() => {});
  return (
    <div className="inputStep">
      <input
        type="text"
        ref={inputRef}
        value={num}
        onBlur={() => inputBlur()}
        onChange={(e) => changeNum(EChangeType.Update, e)}
        className="box"
        onMouseEnter={() => onMouseEnterInput()}
      />
      <div
        className={classNames('mask', { show: isMaskShow })}
        onMouseEnter={() => onMouseEnterInput()}
        onMouseLeave={() => onMouseLeaveInput()}
        onDoubleClick={() => foceInput()}
      >
        <div className="button" onClick={() => changeNum(EChangeType.Decrease)}>
          -
        </div>
        <div
          className="slider"
          onMouseDown={(e) => sliderDown(e)}
          onMouseMove={(e) => sliderMove(e)}
          onMouseUp={() => sliderUp()}
          onMouseLeave={(e) => sliderLeave(e)}
        ></div>
        <div className="button" onClick={() => changeNum(EChangeType.Increase)}>
          +
        </div>
      </div>
    </div>
  );
}
